package com.codi.bus.core.service.organ.impl;

import com.alibaba.fastjson.JSONObject;
import com.codi.base.util.BigDecimalUtil;
import com.codi.base.util.MoneyUtils;
import com.codi.bus.constant.RuleConstant;
import com.codi.bus.core.dao.LookupDao;
import com.codi.bus.core.domain.Lookup;
import com.codi.bus.core.domain.LookupKey;
import com.codi.bus.core.resultModel.FundNetValueResult;
import com.codi.bus.core.service.FundDetailService;
import com.codi.bus.core.service.model.OrganBabyModel;
import com.codi.bus.core.service.model.TradeLimitModel;
import com.codi.bus.core.service.organ.OrganBabyService;
import com.codi.bus.core.vo.OrganBabyVo;
import com.codi.bus.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lvgo
 * @version 1.0
 * @Description: 企业宝
 * @date 2018/6/6 16:32
 */
@Slf4j
@Service("organBabyService")
public class OrganBabyServiceImpl implements OrganBabyService {

    @Autowired
    private LookupDao lookupDao;

    @Autowired
    private FundDetailService fundDetailService;

    @Override
    public List<OrganBabyModel> getOrganBabies() {
        List<Lookup> lookups = lookupDao.getLookupByType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
        lookups = lookups.stream().filter(Lookup::getRuleValid).collect(Collectors.toList());
        List<String> fundCodes = new ArrayList<>();
        Map<String, String> nameMap = new HashMap<>();
        Map<String, String> reportMap = new HashMap<>();
        for (Lookup lookup : lookups) {
            fundCodes.add(lookup.getRuleValue());
            nameMap.put(lookup.getRuleValue(), lookup.getRuleText());
            reportMap.put(lookup.getRuleValue(), lookup.getRuleCreateUserId());
        }

        log.info("organ baby fundCodes=[{}]", fundCodes);

        Date now = new Date();

        List<OrganBabyModel> results = new ArrayList<>(fundCodes.size());


        for (String fundCode : fundCodes) {
            FundNetValueResult netValueResult = fundDetailService.getFundNetValue(fundCode, now);

            OrganBabyModel model = new OrganBabyModel();
            Lookup lookup = new Lookup();
            lookup.setRuleValue(fundCode);
            lookup.setRuleType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
            lookup = lookupDao.getLookupByKey(lookup);
            model.setFundCode(netValueResult.getFundCode());
            model.setFundName(nameMap.get(model.getFundCode()));
            model.setTradingDay(netValueResult.getTradingDay());
            model.setFundReport(reportMap.get(model.getFundCode()));

            // 每万份基金单位当日收益（元）
            model.setDailyProfit(netValueResult.getDailyProfit());
            model.setDailyProfitStr(MoneyUtils.formatMoney(netValueResult.getDailyProfit(), 4));

            // 最近7日折算年收益率（%）
            model.setLatestWeeklyYield(netValueResult.getLatestWeeklyYield());
            model.setLatestWeeklyYieldStr(MoneyUtils.formatMoneyPercentNoRund(netValueResult.getLatestWeeklyYield(), 2));
            List<TradeLimitModel> tradeLimitModels = new ArrayList<>();
            // 企业宝交易显示不再使用恒生
            String ruleLimitValue = lookup.getRuleLimitValue();
            if (com.codi.bus.util.LookupUtil.isJSONObject(ruleLimitValue)) {
                TradeLimitModel tradeLimitModel = new TradeLimitModel();
                JSONObject father = JSONObject.parseObject(ruleLimitValue);
                JSONObject child = father.getJSONObject("org");
                String minMoney = child.getString("minMoney");
                String reminder = child.getString("reminder");
                tradeLimitModel.setMinValue(BigDecimalUtil.ConvertToBigDecimal(minMoney));
                tradeLimitModel.setMinMoney(minMoney);
                tradeLimitModel.setReminder(reminder);
                tradeLimitModels.add(tradeLimitModel);
            }
            model.setLimits(tradeLimitModels);

            results.add(model);
        }
        // sort
        results.sort((o1, o2) -> o2.getLatestWeeklyYield().compareTo(o1.getLatestWeeklyYield()));
        return results;
    }

    @Override
    public void addOrganBaby(Lookup lookup) {
        lookup.setRuleType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
        lookup.setRuleCreateDate(new Date());
        lookupDao.insertSelective(lookup);
    }

    @Override
    public void updateOrganBaby(Lookup lookup) {
        lookupDao.updateByRuleTypeAndRuleValue(lookup);
    }

    /**
     * 获取推荐的企业宝
     *
     * @return
     */
    @Override
    public OrganBabyModel getCommentBaby() {
        OrganBabyModel model = new OrganBabyModel();
        // must have one lookup
        Lookup lookup = lookupDao.getLookupByType(RuleConstant.APP_HOME_DISPLAY_ORGAN_BABY).get(0);
        if (lookup.getRuleStatus() == 0) {
            List<OrganBabyModel> organBabies = this.getOrganBabies();
            model = organBabies.get(0);
            return model;
        }
        lookup.setRuleType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
        lookup = lookupDao.getLookupByKey(lookup);
        // if lookup rule_lu_status is 0 暂取 企业宝任意一只
        Date now = new Date();
        FundNetValueResult netValueResult;
        netValueResult = fundDetailService.getFundNetValue(lookup.getRuleValue(), now);
        model.setFundCode(netValueResult.getFundCode());
        model.setFundName(lookup.getRuleText());
        model.setTradingDay(netValueResult.getTradingDay());
        model.setFundReport(lookup.getRuleCreateUserId());
        // 每万份基金单位当日收益（元）
        model.setDailyProfit(netValueResult.getDailyProfit());
        model.setDailyProfitStr(MoneyUtils.formatMoney(netValueResult.getDailyProfit(), 4));
        // 最近7日折算年收益率（%）
        model.setLatestWeeklyYield(netValueResult.getLatestWeeklyYield());
        model.setLatestWeeklyYieldStr(MoneyUtils.formatMoneyPercentNoRund(netValueResult.getLatestWeeklyYield(), 2));
        List<TradeLimitModel> tradeLimitModels = new ArrayList<>();
        String ruleLimitValue = lookup.getRuleLimitValue();
        if (com.codi.bus.util.LookupUtil.isJSONObject(ruleLimitValue)) {
            TradeLimitModel tradeLimitModel = new TradeLimitModel();
            JSONObject father = JSONObject.parseObject(ruleLimitValue);
            JSONObject child = father.getJSONObject("org");
            String minMoney = child.getString("minMoney");
            String reminder = child.getString("reminder");
            tradeLimitModel.setMinValue(BigDecimalUtil.ConvertToBigDecimal(minMoney));
            tradeLimitModel.setMinMoney(minMoney);
            tradeLimitModel.setReminder(reminder);
            tradeLimitModels.add(tradeLimitModel);
        }
        model.setLimits(tradeLimitModels);
        return model;
    }

    /**
     * 后台获取推荐的企业宝
     *
     * @return
     */
    @Override
    public OrganBabyModel getManageComment() {
        Lookup lookup = lookupDao.getLookupByType(RuleConstant.APP_HOME_DISPLAY_ORGAN_BABY).get(0);
        if (lookup.getRuleStatus() == 0) {
            return null;
        } else {
            return getCommentBaby();
        }
    }

    @Override
    public void setRecommendOrganBaby(String fundCode) {
        Lookup lookup = new Lookup();
        lookup.setRuleType(RuleConstant.APP_HOME_DISPLAY_ORGAN_BABY);
        lookup.setRuleValue(fundCode);
        if ("-1".equalsIgnoreCase(fundCode)) {
            // 取消，自定义
            lookup.setRuleStatus(0);
            lookupDao.updateByRuleType(lookup);
        } else {
            LookupKey lookupKey = new LookupKey();
            lookupKey.setRuleType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
            lookupKey.setRuleValue(fundCode);
            Lookup lookup1 = lookupDao.getLookupByKey(lookupKey);
            if (lookup1 == null) {
                throw new BaseException("请选择已上线的基金");
            }
            // 设置
            lookup.setRuleStatus(1);
            lookupDao.updateByRuleType(lookup);
        }
    }

    /**
     * 企业宝上线下线
     *
     * @param fundCode
     */
    @Override
    public void babyIsValid(String fundCode, Integer state) {
        Lookup lookup = new Lookup();
        lookup.setRuleType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
        lookup.setRuleValue(fundCode);
        if (state == 0) {
            OrganBabyModel manageComment = getManageComment();
            if (manageComment.getFundCode() != null && manageComment.getFundCode().equals(fundCode)) {
                throw new BaseException("不能将已经推荐的基金下线");
            }
            lookup.setRuleValid(false);
        } else {
            lookup.setRuleValid(true);
        }
        lookupDao.updateByRuleTypeAndRuleValue(lookup);
    }

    /**
     * 获取所有线上企业宝
     *
     * @return
     */
    @Override
    public List<OrganBabyVo> getOnlineBabies() {
        List<Lookup> lookups = lookupDao.getLookupByType(RuleConstant.RULE_LOOKUP_TYPE_ORGAN_BAO);
        ArrayList<OrganBabyVo> organBabyVos = new ArrayList<>();
        lookups.forEach(lookup -> {
            OrganBabyVo organBabyVo = OrganBabyVo.builder()
                .fundCode(lookup.getRuleValue())
                .fundName(lookup.getRuleText())
                .build();
            organBabyVos.add(organBabyVo);
        });
        return organBabyVos;
    }
}

